package com.engine.jucailinkq.attendance.component.persongroup.commonutil;

import com.engine.jucailinkq.attendance.enums.PersonGroupListTypeEnum;
import com.engine.jucailinkq.common.util.DateUtil;
import com.engine.jucailinkq.common.util.DbTools;
import com.engine.jucailinkq.common.util.Utils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import weaver.conn.RecordSet;
import weaver.general.Util;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class PersongroupCommonUtil {
    /**
     *
     * @param calendarMap  key:年份，value：明细数据
     * @return
     */
    public static Map<String, List<Map<String,Object>>> getDayByCalendarMap(Map<String,String> calendarMap){
        Map<String, List<Map<String,Object>>> dataList = Maps.newHashMap();
        String sql = "select mainid,rq,mc,rqlx,xq,sc from uf_qyrl_dt1 where mainid in ";
        String mainids = "";
        for(Map.Entry<String,String> entry : calendarMap.entrySet()){
            mainids = mainids + entry.getValue() +",";
        }
        mainids = mainids.substring(0,mainids.length()-1);
        sql = sql +" ("+mainids+") ";
        log.debug("sql : {}",sql);
        List<Map<String,Object>> list = DbTools.getSqlToList(sql);
        Map<String,List<Map<String,Object>>> collect = list.stream().collect(Collectors.groupingBy(e -> e.get("mainid").toString()));


        calendarMap.entrySet().forEach(e -> {
            dataList.put(e.getKey(),collect.get(e.getValue()));
        });

        return dataList;
    }
    public static int getBetweenDays(Map<String, Object> data){
        //主表数据id
        String id = Util.null2String(data.get("id"));
        //规律排班模块Id
        String modeId = Util.null2String(data.get("modeId"));
        //排班结果模块Id
        String formmodeid = Util.null2String(data.get("formmodeid"));
        //生成天数
        int day = Integer.valueOf(Util.null2String(data.get("day")));
        //企业日历
        String qyrl = Util.null2String(data.get("qyrl"));
        //节假日处理 0:改班，1：跳过，2：不处理
        String jjrcl = Util.null2String(data.get("jjrcl"));
        //公休日处理 0：改班，1：跳过，2：不处理
        String gxrcl = Util.null2String(data.get("gxrcl"));
        //生效日期
        String bdate = Util.null2String(data.get("bdate"));
        //执行日期
        String nowDate = Util.null2String(data.get("executeDate"));
        //排班方式
        String pbfs = Util.null2String(data.get("pbfs"));
        //改班班次
        String gbbc = Util.null2String(data.get("gbbc"));


        //规律排班明细表数据
        String sql = "select ksts,jsts,hxbz,bcmc from uf_jcl_kq_glpb_dt1 where mainid=?";
        List<Map<String,Object>> detailDataList = DbTools.getSqlToList(sql,id);
        //规律排班适用组织数据
        sql = "select dx,dxlx,aqjb from uf_jcl_syzz where modeid=? and dataid=?";
       // List<Map<String,Object>> organizationList = DbTools.getSqlToList(sql,modeId,id);
        //规律排班所用企业日历数据
        sql = "select rlmc,nd,rq,rqlx from uf_jcl_kq_rlxx where rlmc=?";
       // List<Map<String,Object>> calendarList = DbTools.getSqlToList(sql,qyrl);
//        Map<String,String> calendarMap = calendarList.stream().collect(Collectors.toMap(e->Util.null2String(e.get("nd")),e->Util.null2String(e.get("id"))));
//        log.debug("calendarMap : {}",calendarMap);
//        Map<String, List<Map<String,Object>>> detailDataGroupingByYear = calendarList.stream().collect(Collectors.groupingBy(e ->e.get("nd").toString()));
//
        //生效日期与当前日期相差年份
        int betweenYears =  DateUtil.getBetWeenYears(bdate,nowDate);
        //循环总天数
       // int circulateDays = Integer.valueOf(detailDataList.get(detailDataList.size()-1).get("jsts").toString());
        int betweenDays = DateUtil.getBetWeenDays(bdate,nowDate);
        /**计算生效日期到当前日期的总天数*/
        if (betweenYears == 0){
            String dateCondition = "rq >='"+bdate+"' and rq <'"+nowDate+"'";
            int needSkipDay = getNeedSkipDay(jjrcl,gxrcl,qyrl,dateCondition);
            log.debug("needSkipDay : [{}]",needSkipDay);
            betweenDays = betweenDays-needSkipDay;

        }else if(betweenYears > 0){
            int needSkipDay = 0;
            int bgYear = Integer.valueOf(bdate.split("-")[0]);
            for(int i=0;i<=betweenYears;i++){
                int currentYear = bgYear +i;
                String endTime = currentYear+"-12-31";
                if(i == 0){
                    String dateCondition = "rq >='"+bdate+"' and rq <='"+endTime+"'";
                    needSkipDay += getNeedSkipDay(jjrcl,gxrcl,qyrl,dateCondition);
                }else if (i == betweenYears){
                    String beginTime = currentYear + "-01-01";
                    String dateCondition = "rq >='"+beginTime+"' and rq <'"+nowDate+"'";
                    needSkipDay += getNeedSkipDay(jjrcl,gxrcl,qyrl,dateCondition);
                }else {
                    String beginTime = currentYear + "-01-01";
                    String dateCondition = "rq >='"+beginTime+"' and rq <='"+endTime+"'";
                    needSkipDay += getNeedSkipDay(jjrcl,gxrcl,qyrl,dateCondition);
                }
            }
            log.debug("needSkipDay : [{}]",needSkipDay);
            betweenDays = betweenDays-needSkipDay;
        }
        return betweenDays;
    }


    public static int getNeedSkipDay(String jjrcl,String gxrcl,String rlmc,String dateCondition){
        String sql = "select count(0) num from uf_jcl_kq_rlxx where rlmc=? and "+dateCondition;
        String conditionSql = "";
        if ("1".equals(jjrcl)){
            //节假日为跳过
            conditionSql = conditionSql + " rqlx=1";
        }
        if ("1".equals(gxrcl)){
            //公休日为跳过
            if ("".equals(conditionSql)){
                conditionSql = conditionSql + " rqlx=2 or rqlx=3";
            }else {
                conditionSql = conditionSql + " or rqlx=2 or rqlx=3";
            }
        }
        if (!"".equals(conditionSql)){
            sql = sql + " and ( "+conditionSql+")";
        }
        log.debug("getNeedSkipDay sql : {},rlmc : {}",sql,rlmc);
        Map<String,Object> objectMap = DbTools.getSqlToMap(sql,rlmc);
        int needSkipDay = Integer.valueOf(objectMap.get("num").toString());
        return needSkipDay;
    }

    /**
     * 规律排班插入排班结果公共方法
     * @param organizationList
     * @param insertDataList
     * @param formmodeid
     * @return
     */
    public static boolean insertShiftSchedulingResults(List<Map<String,Object>> organizationList,List<Map<String,Object>> insertDataList,String formmodeid){
        RecordSet rs = new RecordSet();
        List<List> addlist = Lists.newArrayList();
        String sql = "delete from uf_pbjg where bcrq>= ? and bcrq<=? and pbtj="+insertDataList.get(0).get("pbtj");
        String startDate = Util.null2String(insertDataList.get(0).get("bcrq"));
        String endDate = Util.null2String(insertDataList.get(insertDataList.size()-1).get("bcrq"));
        Set<String> psersons = Sets.newHashSet();
        Set<String> psersonsGroups = Sets.newHashSet();
        Set<String> departments = Sets.newHashSet();
        Set<String> subCompanys = Sets.newHashSet();
        for (Map<String,Object> organization: organizationList){
            String rqlx = Util.null2String(organization.get("rqlx"));
            for (Map<String,Object> insertData : insertDataList){
                ArrayList<Object> list = new ArrayList<>();
                list.add(insertData.get("bcbdsj"));
                list.add(insertData.get("pbtj"));
                list.add(insertData.get("pbgl"));
                list.add(organization.get("dxlx"));
                if ("0".equals(organization.get("dxlx"))){
                    //人员
                    list.add(Util.null2String(organization.get("dx")).split("-")[0]);
                    list.add(null);
                    list.add(null);
                    list.add(null);
                    psersons.add(Util.null2String(organization.get("dx")).split("-")[0]);

                }else if ("1".equals(organization.get("dxlx"))){
                    //人员分组
                    list.add(null);
                    list.add(Util.null2String(organization.get("dx")).split("-")[0]);
                    list.add(null);
                    list.add(null);
                    psersonsGroups.add(Util.null2String(organization.get("dx")).split("-")[0]);
                }else if ("2".equals(organization.get("dxlx"))){
                    //部门
                    list.add(null);
                    list.add(null);
                    list.add(Util.null2String(organization.get("dx")).split("-")[0]);
                    list.add(null);
                    departments.add(Util.null2String(organization.get("dx")).split("-")[0]);
                }else if ("3".equals(organization.get("dxlx"))){
                    //分部
                    list.add(null);
                    list.add(null);
                    list.add(null);
                    list.add(Util.null2String(organization.get("dx")).split("-")[0]);
                    subCompanys.add(Util.null2String(organization.get("dx")).split("-")[0]);
                }
                list.add(insertData.get("bcrq"));
                if (!rqlx.equals("")){
                    list.add(rqlx);
                }else {
                    list.add(insertData.get("rqlx"));
                }
                list.add(insertData.get("sfxx"));
                list.add(insertData.get("sfdkpp"));
                list.add(insertData.get("bcxx"));
                list.add(insertData.get("hxbz"));
                list.add(insertData.get("pbrq"));
                list.add(insertData.get("pbsj"));
                list.add(formmodeid);
                list.add(1);
                list.add(0);
                list.add(DateUtil.getCurrentDate());
                list.add(DateUtil.getCurrentTime().split(" ")[1]);
                list.add(UUID.randomUUID().toString());
                addlist.add(list);
            }

        }

        boolean result = false;
        if (insertDataList.size() >0){
            //老的排班结果删除
            String pbgl = insertDataList.get(0).get("pbgl").toString();
            String deleteSql = sql + " and pbgl = ?";
            log.debug("deleteSql : {}",deleteSql);
            DbTools.update(rs,deleteSql,startDate,endDate,pbgl);
        }

        if (addlist.size() >0){
            log.debug("addlist :[{}]",addlist);
            String insertSql = "insert into uf_pbjg (bcbdsj,pbtj,pbgl,dxlx,pbdxry,pbdxryfz,pbdxbm,pbdxfb,bcrq,rqlx,sfxx,sfdkpp,bcxx,hxbz,pbrq,pbsj,formmodeid,modedatacreater,modedatacreatertype,modedatacreatedate,modedatacreatetime,MODEUUID) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
             result =rs.executeBatchSql(insertSql,addlist);
            log.debug("result :[{}]",result);
        }
        return result;
    }

    /**
     * 删除过期规律排班数据
     */
    public static void deleteExpireData(String regularId,String edate){
        String sql = "delete from uf_pbjg where pbgl=? and bcrq > ?";
        DbTools.update(sql,regularId,edate);
    }


    /**
     * 日历排班插入排班结果公共方法
     * @param organizationList
     * @param formmodeid
     * @return
     */
    public static boolean insertSchedulingResults(List<Map<String,Object>> organizationList,String formmodeid){
        RecordSet rs = new RecordSet();
        List<List> addlist = Lists.newArrayList();
        Set<String> psersons = Sets.newHashSet();
        Set<String> psersonsGroups = Sets.newHashSet();
        Set<String> departments = Sets.newHashSet();
        Set<String> subCompanys = Sets.newHashSet();
        for (Map<String,Object> organization: organizationList){
            String rqlx = Util.null2String(organization.get("rqlx"));
                ArrayList<Object> list = new ArrayList<>();
                list.add(organization.get("bcsdxx"));
                list.add(organization.get("pbtj"));
                list.add(organization.get("pbgl"));
                list.add(organization.get("dxlx"));
                if ("0".equals(organization.get("dxlx"))){
                    //人员
                    list.add(Util.null2String(organization.get("dx")).split("-")[0]);
                    list.add(null);
                    list.add(null);
                    list.add(null);
                    psersons.add(Util.null2String(organization.get("dx")).split("-")[0]);

                }else if ("1".equals(organization.get("dxlx"))){
                    //人员分组
                    list.add(null);
                    list.add(Util.null2String(organization.get("dx")).split("-")[0]);
                    list.add(null);
                    list.add(null);
                    psersonsGroups.add(Util.null2String(organization.get("dx")).split("-")[0]);
                }else if ("2".equals(organization.get("dxlx"))){
                    //部门
                    list.add(null);
                    list.add(null);
                    list.add(Util.null2String(organization.get("dx")).split("-")[0]);
                    list.add(null);
                    departments.add(Util.null2String(organization.get("dx")).split("-")[0]);
                }else if ("3".equals(organization.get("dxlx"))){
                    //分部
                    list.add(null);
                    list.add(null);
                    list.add(null);
                    list.add(Util.null2String(organization.get("dx")).split("-")[0]);
                    subCompanys.add(Util.null2String(organization.get("dx")).split("-")[0]);
                }
                list.add(organization.get("bcrq"));
                if (!rqlx.equals("")){
                    list.add(rqlx);
                }else {
                    list.add(organization.get("rqlx"));
                }
                list.add(organization.get("sfxx"));
                list.add(organization.get("sfdkpp"));
                list.add(organization.get("bcxx"));
                list.add(organization.get("hxbz"));
                list.add(organization.get("pbrq"));
                list.add(organization.get("pbsj"));
                list.add(formmodeid);
                list.add(1);
                list.add(0);
                list.add(DateUtil.getCurrentDate());
                list.add(DateUtil.getCurrentTime().split(" ")[1]);
                list.add(UUID.randomUUID().toString());
                addlist.add(list);
        }

        boolean result = false;

        if (addlist.size() >0){
            log.debug("addlist :[{}]",addlist);
            String insertSql = "insert into uf_pbjg (bcbdsj,pbtj,pbgl,dxlx,pbdxry,pbdxryfz,pbdxbm,pbdxfb,bcrq,rqlx,sfxx,sfdkpp,bcxx,hxbz,pbrq,pbsj,formmodeid,modedatacreater,modedatacreatertype,modedatacreatedate,modedatacreatetime,MODEUUID) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
            result =rs.executeBatchSql(insertSql,addlist);
            log.debug("result :[{}]",result);
        }
        return result;
    }


    /***
     * 获得人员所在在的人员分组id
     * @param personnelGrouping 人员分组集合
     * @param userId 人员id
     * @return 人员分组主键ID集合
     */
    public static Set<String> getPersonnelGroupingByPerson(List<Map<String,Object>> personnelGrouping,String userId,String date){
        Map<String,List<Map<String,Object>>> collect = personnelGrouping.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("mainid"))));
        Set<String> personnelGroupIds = Sets.newHashSet();
        log.debug("getPersonnelGroupingByPerson collect : {}",collect);
        if (userId == null || "".equals(userId)){
            return personnelGroupIds;
        }
        personnelGroupIds = getPersonnelGroupByPerson(personnelGrouping,userId,date).stream().map(e->e.get("mainid").toString()).collect(Collectors.toSet());

        return personnelGroupIds;
    }


    /***
     * 获得人员所在人员分组
     * @param personnelGrouping 人员分组集合
     * @param userId 人员id
     * @return 人员分组主键ID集合
     */
    public static List<Map<String,Object>> getPersonnelGroupByPerson(List<Map<String,Object>> personnelGrouping,String userId,String date){
        Map<String,List<Map<String,Object>>> collect = personnelGrouping.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("mainid"))));
        List<Map<String,Object>> resultList = Lists.newArrayList();
        log.debug("getPersonnelGroupingByPerson collect : {}",collect);
        if (userId == null || "".equals(userId)){
            return resultList;
        }
        for (Map.Entry<String,List<Map<String,Object>>> e : collect.entrySet()){
            List<Map<String,Object>> value = e.getValue();
            for (Map<String,Object> data :value ){
                String edate = Util.null2String(data.get("edate"));
                String bdate = Util.null2String(data.get("bdate"));
                if (date != null && !date.equals("")){
                    if ((!"".equals(bdate) && DateUtil.getTime(date).compareTo(DateUtil.getTime(bdate)) <0) ||
                            (!"".equals(edate) && DateUtil.getTime(date).compareTo(DateUtil.getTime(edate)) > 0)){
                        continue;
                    }
                }
                String empid = Util.null2String(data.get("empid"));
                String filters = Util.null2String(data.get("filters"));
                String sqltj = Util.null2String(data.get("sqltj"));
                log.debug(" empid : {},userId : {}",empid,userId);
                if (empid.equals(userId)){
                    resultList.add(data);
                }else if (!"".equals(filters)){
                    filters = filters.replace("ａｎｄ","and");
                    filters = filters.replace("ｏｒ","or");
                    //条件清单
                    String sql = "select id,seclevel from hrmresource where 1=1 ";
                    if (filters.contains("field")){
                        sql = "select a.id,a.seclevel from hrmresource a left join cus_fielddata b on a.id=b.id where scope='HrmCustomFieldByInfoType'  and "+filters;
                    }else {
                        sql = sql+ " and "+filters;
                    }
                    log.debug("getPersonnelGroupingByPerson filter sql : {}",sql);
                    List<Map<String,Object>> dataList = DbTools.getSqlToList(sql);
                    for (Map<String,Object> dataMap :dataList){
                        String hrmId = Util.null2String(dataMap.get("id"));
                        if (hrmId.equals(userId)){
                            resultList.add(data);
                        }
                    }
                }else if (!"".equals(sqltj)){
                    sqltj = Utils.converSQL(sqltj);
                    log.debug("getPersonnelGroupingByPerson sqltj : [{}]",sqltj);
                    List<Map<String,Object>> dataList = DbTools.getSqlToList(sqltj);
                    for (Map<String,Object> dataMap :dataList){
                        String hrmId = Util.null2String(dataMap.get("id"));
                        if (hrmId.equals(userId)){
                            resultList.add(data);
                        }
                    }
                }
            }
        }


        return resultList;
    }

    /**
     * 获得人员分组所包含的所有用户id
     * @param personnelGroupingList 人员分组集合
     * @return userIDs 人员集合
     */
    public static Set<String> getUserIdsByPersonnelGrouping(List<Map<String,Object>> personnelGroupingList,String date){
        Set<String> userIds = Sets.newHashSet();
        log.debug("getUserIdsByPersonnelGrouping personnelGroupingList :[{}]",personnelGroupingList);
        for (Map<String,Object> data:personnelGroupingList){

            //生效日期
            String bdate = Util.null2String(data.get("bdate"));
            //失效日期
            String edate = Util.null2String(data.get("edate"));
            if ((!"".equals(bdate) && DateUtil.getTime(date).compareTo(DateUtil.getTime(bdate)) <0) ||
                    (!"".equals(edate) && DateUtil.getTime(date).compareTo(DateUtil.getTime(edate)) > 0)){
                continue;
            }

            String empid = Util.null2String(data.get("empid"));
            String filters = Util.null2String(data.get("filters"));
            String list_type = Util.null2String(data.get("list_type"));
            String sqltj = Util.null2String(data.get("sqltj"));
            if (PersonGroupListTypeEnum.PERSON.getKey().equals(list_type) && !"".equals(empid)){
                //人员清单
                userIds.add(empid);
            }else if (PersonGroupListTypeEnum.CONDITION.getKey().equals(list_type) && !"".equals(filters)){
                filters = filters.replace("ａｎｄ","and");
                filters = filters.replace("ｏｒ","or");
                //条件清单
                String sql = "select id,seclevel from hrmresource where 1=1 ";
                if (filters.contains("field")){
                    sql = "select a.id,a.seclevel from hrmresource a left join cus_fielddata b on a.id=b.id where scope='HrmCustomFieldByInfoType'  and "+filters;
                }else {
                    sql = sql+ " and "+filters;
                }
                log.debug("getPersonnelGroupingByPerson filter sql : {}",sql);
                List<Map<String,Object>> dataList = DbTools.getSqlToList(sql);
                for (Map<String,Object> dataMap :dataList){
                    String hrmId = Util.null2String(dataMap.get("id"));
                    userIds.add(hrmId);
                }
            }else if (PersonGroupListTypeEnum.SQLCONDITION.getKey().equals(list_type) && !"".equals(sqltj)){
                sqltj = Utils.converSQL(sqltj);
                log.info("getPersonnelGroupingByPerson sqltj : [{}]",sqltj);
                List<Map<String,Object>> dataList = DbTools.getSqlToList(sqltj);
                for (Map<String,Object> dataMap :dataList){
                    String hrmId = Util.null2String(dataMap.get("id"));
                    userIds.add(hrmId);
                }
            }
        }
        log.debug("userIds size :[{}]",userIds.size());
        return userIds;
    }

    /**
     * 获得人员分组集合
     * @return
     */
    public static Map<String,Object> getPersonGroup(){
        String sql = "select id,name from uf_ryqz";
        return DbTools.getSqlToMapList(sql);
    }

    /**
     * 获得部门集合
     * @return
     */
    public static Map<String,Object> getDepartMent(){
        String sql = "select id,departmentname name from hrmdepartment";
        return DbTools.getSqlToMapList(sql);
    }
    /**
     * 获得分部集合
     * @return
     */
    public static Map<String,Object> getSubCompany(){
        String sql = "select id,subcompanyname name from hrmsubcompany";
        return DbTools.getSqlToMapList(sql);
    }
    /**
     * 获得班次信息集合
     * @return
     */
    public static Map<String,Object> getClassesInformation(){
        String sql = "select id,mc name from uf_jcl_kq_bcxx";
        return DbTools.getSqlToMapList(sql);
    }
    /**
     * 获得候选班次集合
     * @return
     */
    public static Map<String,Object> getCandidateTeam(){
        String sql = "select id,mc name from uf_jcl_kq_hxbz";
        return DbTools.getSqlToMapList(sql);
    }

    /**
     * 获得班次信息名称与简称集合
     * @return
     */
    public static Map<String,String> getClassesAndSimpleNameInformation(){
        String sql = "select id,mc name,jc simplename,ys from uf_jcl_kq_bcxx";
        return DbTools.getSimpleNameMap(sql);
    }


}
